package com.lyf.scm.admin.domain.service.impl;


import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.github.pagehelper.PageInfo;
import com.lyf.scm.admin.api.dto.*;
import com.lyf.scm.admin.domain.excel.dto.SalesDirectlyReadDTO;
import com.lyf.scm.admin.domain.remote.allocationservice.facade.*;
import com.lyf.scm.admin.domain.remote.bigdata.facade.BlOlapFacade;
import com.lyf.scm.admin.domain.remote.network.facade.NetworkFacade;
import com.lyf.scm.admin.domain.service.PermissionService;
import com.lyf.scm.admin.domain.service.SalesPlanDirectlyService;
import com.lyf.scm.admin.domain.util.DirectlyDataListener;
import com.lyf.scm.admin.domain.util.OtherTargetHandleUtil;
import com.lyf.scm.common.constants.CommonConstants;
import com.lyf.scm.common.enums.*;
import com.lyf.scm.common.model.ExcelExportDTO;
import com.lyf.scm.common.model.ExcelExportDataDTO;
import com.lyf.scm.common.model.SalesPlanSelectDTO;
import com.lyf.scm.common.util.AdvancedSearchUtil;
import com.lyf.scm.common.util.ExcelExportUtil;
import com.lyf.scm.common.util.date.MyDateUtil;
import com.lyf.scm.common.util.style.DirectlyCellWriterHandler;
import com.rome.arch.core.exception.RomeException;
import com.rome.user.DTO.ApplicationUserInfoDTO;
import com.rome.user.common.utils.UserContext;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.lyf.scm.common.util.AdvancedSearchUtil.getExcelDateTitle;

/**
 * description:
 * 直营预测计划
 *
 * @author: haodong
 * @data: 2020/8/3 10:26
 */
@Slf4j
@Service
public class SalesPlanDirectlyServiceImpl implements SalesPlanDirectlyService {

    @Resource
    private SalesPlanDirectlyFacade salesPlanDirectlyFacade;
    @Resource
    private NetworkFacade nateWorkFacade;
    @Resource
    private BlOlapFacade blOlapFacade;
    @Resource
    private PermissionService permissionService;
    @Resource
    private SalesPlanEsFacade salesPlanEsFacade;
    @Resource
    private DirectlyStoreFacade directlyStoreFacade;
    @Resource
    private SalesPlanEsLazyLoadingFacade esLazyLoadingFacade;
    @Resource
    private OperationLogRecordFacade logRecordFacade;
    @Resource
    private OtherTargetGeneralHandlerFacade otherTargetGeneralHandlerFacade;
    @Resource
    @Lazy
    private SalesPlanDirectlyService salesPlanDirectlyService;
    @Value("${filePath}")
    private String filePath;
    // 权限等级，开发测试用
    // private Integer permissionLevel = 3;

    @Override
    public PlanResponseDTO<SalesPlanDirectlyReturnDTO> listBySelective(SalesPlanDirectlyDTO salesPlanDirectly) {
        // 根据日期获取间隔日期集合,没有结束时间，默认14周
        List<Map<String, String>> weekDates = MyDateUtil.getWeekDateList(salesPlanDirectly.getStartTime(), CommonConstants.WEEK_SIZE);
        List<String> dateList = weekDates.stream().map(map -> map.get("startTime")).collect(Collectors.toList());
        Integer permissionLevel = permissionService.getPermissionLevel();
        // 查询
        EsAggregationDTO esQuery = getEsQuery(salesPlanDirectly, permissionLevel, dateList, Boolean.TRUE);
        PageInfo<EsReturnDTO> pageInfo = esLazyLoadingFacade.pageQuery(esQuery);
        if (pageInfo == null || CollectionUtils.isEmpty(pageInfo.getList())) {
            return null;
        }
        List<EsReturnDTO> paramList = pageInfo.getList();
        //获取实际销量
        //获取通用其它指标传输实体对象
        OtherTargetGeneralQueryDTO otherQueryDTO = OtherTargetHandleUtil.getGeneralQueryDTO(esQuery, paramList, OtherTargetsEnum.DIRECTLY_PALN);
        OtherTargetHandleUtil.handleResult(otherTargetGeneralHandlerFacade.getNecessaryOtherTargets(otherQueryDTO), paramList);
        // 到货量
        getOtherTarget(esQuery.getEsQuery(), paramList, weekDates, permissionLevel, Boolean.TRUE, esQuery.getUnitType());
        // 解析es查询数据
        List<SalesPlanDirectlyReturnDTO> resultList = analyzeData(paramList, permissionLevel);
        PlanResponseDTO<SalesPlanDirectlyReturnDTO> planResponse = new PlanResponseDTO<>();
        planResponse.setInfoList(resultList);
        planResponse.setTotal(pageInfo.getTotal());
        planResponse.setPageNum(pageInfo.getPageNum());
        planResponse.setHasNextPage(pageInfo.isHasNextPage());
        planResponse.setDateList(MyDateUtil.processCyclesDate2(weekDates, "MM.dd"));
        return planResponse;
    }


    @Override
    public PlanResponseDTO<SalesPlanDirectlyReturnDTO> listAllByCycles(SalesPlanDirectlyDTO salesPlanDirectly) {
        List<Map<String, String>> weekDates;
        if (salesPlanDirectly.getEndTime() == null) {
            //根据日期获取间隔日期集合,没有结束时间，默认14周
            weekDates = MyDateUtil.getWeekDateList(salesPlanDirectly.getStartTime(), CommonConstants.WEEK_SIZE);
        } else {
            weekDates = MyDateUtil.getWeekDateList(salesPlanDirectly.getStartTime(), salesPlanDirectly.getEndTime());
        }
        List<String> dateList = weekDates.stream().map(map -> map.get("startTime")).collect(Collectors.toList());
        Integer permissionLevel = permissionService.getPermissionLevel();
        // 查询
        EsAggregationDTO esQuery = getEsQuery(salesPlanDirectly, permissionLevel, dateList, Boolean.FALSE);
        PageInfo<EsReturnDTO> pageInfo = salesPlanEsFacade.queryByGroup(esQuery);
        PlanResponseDTO<SalesPlanDirectlyReturnDTO> planResponse = new PlanResponseDTO<>();
        if (pageInfo == null || CollectionUtils.isEmpty(pageInfo.getList())) {
            planResponse.setInfoList(getAllReturn());
            planResponse.setDateList(MyDateUtil.processCyclesDate2(weekDates, "M.dd"));
            return planResponse;
        }
        List<EsReturnDTO> paramList = pageInfo.getList();
        //获取实际销量
        //获取通用其它指标传输实体对象
        OtherTargetGeneralQueryDTO otherQueryDTO = OtherTargetHandleUtil.getGeneralQueryDTO(esQuery, paramList, OtherTargetsEnum.DIRECTLY_PALN);
        otherQueryDTO.setType(CommonConstants.ONE);
        OtherTargetHandleUtil.handleEchartResult(otherTargetGeneralHandlerFacade.getEchartNecessaryOtherTargets(otherQueryDTO), paramList.get(0).getTargetMap());
        // 到货量
        getOtherTarget(esQuery.getEsQuery(), paramList, weekDates, permissionLevel, Boolean.FALSE, esQuery.getUnitType());
        // 解析es查询数据
        List<SalesPlanDirectlyReturnDTO> resultList = analyzeData(pageInfo.getList(), permissionLevel);

        planResponse.setInfoList(resultList);
        planResponse.setDateList(MyDateUtil.processCyclesDate2(weekDates, "M.dd"));
        return planResponse;

    }

    @Override
    public Boolean update(List<SalesPlanDirectlyDTO> paramDataList, Long unitType) {
        if (CollectionUtils.isEmpty(paramDataList)) {
            throw new RomeException(ResponseMsg.PARAM_ERROR_2015.getCode(), ResponseMsg.PARAM_ERROR_2015.getMsg());
        }
        Integer permissionLevel = permissionService.getPermissionLevel();
        return salesPlanDirectlyFacade.updateConfirm(paramDataList, unitType, permissionLevel);
    }

    @Override
    @Async
    public void updateConfirm(List<SalesPlanDirectlyDTO> paramList, Long unitType, OperationLogRecordDTO logRecord, Integer permissionLevel) {
        try {
            salesPlanDirectlyFacade.updateConfirm(paramList, unitType, permissionLevel);
            logRecord.setOpStatus(OperationStatusEnum.SUCCESS.getType());
            logRecord.setFailReason("导入成功，请刷新页面查看");
        } catch (Exception e) {
            log.error("直营预测计划导入失败", e);
            logRecord.setOpStatus(OperationStatusEnum.FAIL.getType());
            logRecord.setFailReason(ResponseMsg.FAIL_2020.getMsg());
        } finally {
            logRecord.setOpEndTime(new Date());
            logRecordFacade.updateOperationLog(logRecord);
        }
    }

    @Override
    public Boolean export(ExcelExportDTO excelExport, Integer type) {
        if (ObjectUtil.isEmpty(type)) {
            throw new RomeException(ResponseMsg.FAIL_2005.getCode(), "未传入导出类型");
        }
        // 创建日志
        String opContent = OperationSourceEnum.ONE_PLAN.getDesc() + "-" + type;
        OperationLogRecordDTO logRecord = this.getLogRecord(opContent, OperationTypeEnum.EXPORT.getType(), UserContext.getApplicationUser());
        OperationLogRecordDTO operationLog = logRecordFacade.insertOperationLog(logRecord);
        // 根据日期获取间隔日期集合,没有结束时间，默认14周
        List<Map<String, String>> weekDates = MyDateUtil.getWeekDateList(excelExport.getStartTime(), CommonConstants.WEEK_SIZE);
        List<String> dateList = weekDates.stream().map(map -> map.get("startTime")).collect(Collectors.toList());
        Integer permissionLevel = permissionService.getPermissionLevel();
        // 查询
        EsAggregationDTO esQuery = getEsQuery(this.transferToDirectlyDTO(excelExport), permissionLevel, dateList, Boolean.TRUE);
        salesPlanDirectlyService.exportExcel(esQuery, weekDates, excelExport.getRowIndex(), permissionLevel, type, operationLog);
        return Boolean.TRUE;
    }

    /**
     * 导出
     *
     * @param esQuery
     * @param weekDates
     * @param rowIndex
     * @param permissionLevel
     * @param type
     * @param operationLog
     * @return {@link ExcelExportDataDTO}
     **/
    @Override
    @Async
    public void exportExcel(EsAggregationDTO esQuery, List<Map<String, String>> weekDates, List<Integer> rowIndex, Integer permissionLevel, Integer type, OperationLogRecordDTO operationLog) {
        File path = new File(filePath);
        if (!path.exists()) {
            path.mkdirs();
        }
        String ext = "";
        try {
            List<String> allTargetsDesc = SalesPlanDirectlyEnum.getDescList();
            List<List<Object>> exportDataList = new ArrayList<>();
            if (ExcelExportTypeEnum.SEARCHED_DATA_EXPORT.getType().equals(type)) {
                EsExportAggregationDTO esExportAggregationDTO = this.TransferToExportAggregation(esQuery);
                EsScrollReturnDTO esScrollReturnDTO;
                List<SalesPlanDirectlyReturnDTO> resultList;
                List<EsReturnDTO> esReturnDTOList;
                do {
                    esScrollReturnDTO = salesPlanEsFacade.exportByGroup(esExportAggregationDTO);
                    esReturnDTOList = esScrollReturnDTO.getEsReturnDTOList();
                    //获取实际销量
                    //获取通用其它指标传输实体对象
                    if (CollectionUtils.isNotEmpty(esReturnDTOList)) {
                        OtherTargetGeneralQueryDTO otherQueryDTO = OtherTargetHandleUtil.getGeneralQueryDTO(esQuery, esReturnDTOList, OtherTargetsEnum.DIRECTLY_PALN);
                        OtherTargetHandleUtil.handleResult(otherTargetGeneralHandlerFacade.getNecessaryOtherTargets(otherQueryDTO), esReturnDTOList);
                    }
                    // 到货量
                    getOtherTarget(esQuery.getEsQuery(), esReturnDTOList, weekDates, permissionLevel, Boolean.TRUE, esQuery.getUnitType());
                    resultList = analyzeExportData(esReturnDTOList, permissionLevel);
                    this.getExportDataList(exportDataList, resultList, allTargetsDesc);
                    esExportAggregationDTO.setAfterKey(esScrollReturnDTO.getAfterKey());
                } while (esScrollReturnDTO.getAfterKey() != null);
                if (org.springframework.util.CollectionUtils.isEmpty(exportDataList)) {
                    throw new RomeException(ResponseMsg.FAIL_2005.getCode(), ResponseMsg.FAIL_2005.getMsg());
                }
            } else {
                List<EsReturnDTO> paramList = esLazyLoadingFacade.queryFromCache(esQuery);
                if (CollectionUtils.isEmpty(paramList)) {
                    throw new RomeException(ResponseMsg.FAIL_2005.getCode(), ResponseMsg.FAIL_2005.getMsg());
                }
                //获取实际销量
                //获取通用其它指标传输实体对象
                OtherTargetGeneralQueryDTO otherQueryDTO = OtherTargetHandleUtil.getGeneralQueryDTO(esQuery, paramList, OtherTargetsEnum.DIRECTLY_PALN);
                OtherTargetHandleUtil.handleResult(otherTargetGeneralHandlerFacade.getNecessaryOtherTargets(otherQueryDTO), paramList);
                if (ExcelExportTypeEnum.CHECKED_BOX_EXPORT.getType().equals(type)) {
                    paramList = rowIndex.stream().map(paramList::get).collect(Collectors.toList());
                }
                // 到货量
                getOtherTarget(esQuery.getEsQuery(), paramList, weekDates, permissionLevel, Boolean.TRUE, esQuery.getUnitType());
                // 解析es查询数据
                List<SalesPlanDirectlyReturnDTO> resultList = analyzeExportData(paramList, permissionLevel);
                this.getExportDataList(exportDataList, resultList, allTargetsDesc);
            }
            //写死静态合并单元格列:渠道，区域，品类，商品，单位
            List<List<String>> mainHeaders = this.getMainHeaders();
            int mergeCellsColumns = mainHeaders.size();
            //加入指标标题
            this.setTargetTitle(mainHeaders);
            //获取excel标题信息
            List<String> dateTitles = MyDateUtil.processCyclesDate2(weekDates, "MM.dd");
            //加入日期标题
            getExcelDateTitle(mainHeaders, dateTitles);
            ExcelExportDataDTO excelExportData = ExcelExportUtil.getExcelExportData(mergeCellsColumns, exportDataList, mainHeaders, allTargetsDesc.size(), new DirectlyCellWriterHandler());
            // 指定文件夹
            String folderName = OperationSourceEnum.ONE_PLAN.getTableType().toString();
            // 获取文件名
            String fileName = ExcelExportUtil.getFileName(OperationSourceEnum.ONE_PLAN.getDesc(), esQuery.getUserId(), type);
            //写文件并返回路径
            ext = ExcelExportUtil.exportExcel(excelExportData, folderName, filePath, fileName);
            operationLog.setOpStatus(OperationStatusEnum.SUCCESS.getType());
        } catch (RomeException e) {
            log.error("直营预测计划导出失败", e);
            operationLog.setOpStatus(OperationStatusEnum.FAIL.getType());
            operationLog.setFailReason(e.getMessage());
        }catch (Exception e) {
            log.error("直营预测计划导出失败", e);
            operationLog.setOpStatus(OperationStatusEnum.FAIL.getType());
            operationLog.setFailReason("导出失败");
        }
        operationLog.setExt(ext);
        operationLog.setOpEndTime(new Date());
        logRecordFacade.updateOperationLog(operationLog);
    }


    @Override
    public Boolean importVerification(MultipartFile file, Long unitType) {
        DirectlyDataListener directlyDataListener = new DirectlyDataListener();
        try {
            EasyExcel.read(file.getInputStream(), SalesDirectlyReadDTO.class, directlyDataListener).sheet().headRowNumber(1).doRead();
        } catch (IOException e) {
            throw new RomeException(ResponseMsg.EXCEPTION.getCode(), "IO异常");
        } catch (ExcelAnalysisException e) {
            throw new RomeException(ResponseMsg.EXCEPTION.getCode(), e.getMessage());
        } catch (Exception e) {
            throw new RomeException(ResponseMsg.EXCEPTION.getCode(), "未知异常");
        }

        List<SalesPlanDirectlyDTO> paramDataList = directlyDataListener.getParamDataList();
        Integer permissionLevel = permissionService.getPermissionLevel();
        paramDataList = paramDataList.stream()
                .filter(e -> e.getConfirmQty().compareTo(BigDecimal.ZERO) != 0).collect(Collectors.toList());
        OperationLogRecordDTO logRecord = getLogRecord("直营预测计划导入", OperationTypeEnum.IMPORT.getType(), UserContext.getApplicationUser());
        logRecord = logRecordFacade.insertOperationLog(logRecord);
        salesPlanDirectlyService.updateConfirm(paramDataList, unitType, logRecord, permissionLevel);
        return Boolean.TRUE;
    }

    private OperationLogRecordDTO getLogRecord(String opContent, String type, ApplicationUserInfoDTO applicationUser) {
        OperationLogRecordDTO logRecord = new OperationLogRecordDTO();
        logRecord.setOpContent(opContent);
        logRecord.setOpStatus(OperationStatusEnum.PROCESSING.getType());
        logRecord.setOpType(type);
        logRecord.setOpSource(OperationSourceEnum.ONE_PLAN.getTableType());
        logRecord.setStartTime(new Date());
        logRecord.setCreator(UserContext.getUserId());
        logRecord.setCreatorName(applicationUser == null ? "system" : applicationUser.getUsername());
        return logRecord;
    }

    /**
     * 获取指标key集合
     *
     * @param level
     * @return
     */
    private List<String> getTargetKeyList(Integer level) {
        if (level == null) {
            throw new RomeException(ResponseMsg.FAIL_2004.getCode(), ResponseMsg.FAIL_2004.getMsg());
        }
        List<String> targetList;
        if (level.equals(CommonConstants.AREA_LEVEL_TWO)) {
            targetList = Stream.of(EsSumColumnEnum.PREDICT_SALES.getColumn(), EsSumColumnEnum.LAST_PREDICT_SALES.getColumn(),
                    EsSumColumnEnum.PREDICT_SALES_DIFFERENCE.getColumn(), EsSumColumnEnum.PREDICT_SALES_SCALE.getColumn(),
                    EsSumColumnEnum.CONFIRM_L2.getColumn(), EsSumColumnEnum.LAST_CONFIRM_L2.getColumn(),
                    EsSumColumnEnum.PREDICT_CONFIRM_L2_DIFFERENCE.getColumn(), EsSumColumnEnum.PREDICT_CONFIRM_L2_SCALE.getColumn(),
                    EsSumColumnEnum.CONFIRM_TARGET_L2.getColumn(), EsSumColumnEnum.CONFIRM_TARGET_L3.getColumn(), EsSumColumnEnum.CONFIRM_TARGET_L4.getColumn(),
                    EsSumColumnEnum.CONFIRM_STATUS_L2.getColumn()).map(String::valueOf).collect(Collectors.toList());
        } else if (level.equals(CommonConstants.AREA_LEVEL_THREE)) {
            targetList = Stream.of(EsSumColumnEnum.PREDICT_SALES.getColumn(), EsSumColumnEnum.LAST_PREDICT_SALES.getColumn(),
                    EsSumColumnEnum.PREDICT_SALES_DIFFERENCE.getColumn(), EsSumColumnEnum.PREDICT_SALES_SCALE.getColumn(),
                    EsSumColumnEnum.CONFIRM_L2.getColumn(), EsSumColumnEnum.CONFIRM_L3.getColumn(), EsSumColumnEnum.LAST_CONFIRM_L3.getColumn(),
                    EsSumColumnEnum.PREDICT_CONFIRM_L3_DIFFERENCE.getColumn(), EsSumColumnEnum.PREDICT_CONFIRM_L3_SCALE.getColumn(),
                    EsSumColumnEnum.CONFIRM_TARGET_L2.getColumn(), EsSumColumnEnum.CONFIRM_TARGET_L3.getColumn(), EsSumColumnEnum.CONFIRM_TARGET_L4.getColumn(),
                    EsSumColumnEnum.CONFIRM_STATUS_L3.getColumn()).map(String::valueOf).collect(Collectors.toList());
        } else if (level.equals(CommonConstants.AREA_LEVEL_FOUR)) {
            targetList = Stream.of(EsSumColumnEnum.PREDICT_SALES.getColumn(), EsSumColumnEnum.LAST_PREDICT_SALES.getColumn(),
                    EsSumColumnEnum.PREDICT_SALES_DIFFERENCE.getColumn(), EsSumColumnEnum.PREDICT_SALES_SCALE.getColumn(),
                    EsSumColumnEnum.CONFIRM_L3.getColumn(), EsSumColumnEnum.CONFIRM_L4.getColumn(), EsSumColumnEnum.LAST_CONFIRM_L4.getColumn(),
                    EsSumColumnEnum.PREDICT_CONFIRM_L4_DIFFERENCE.getColumn(), EsSumColumnEnum.PREDICT_CONFIRM_L4_SCALE.getColumn(),
                    EsSumColumnEnum.CONFIRM_TARGET_L2.getColumn(), EsSumColumnEnum.CONFIRM_TARGET_L3.getColumn(), EsSumColumnEnum.CONFIRM_TARGET_L4.getColumn(),
                    EsSumColumnEnum.CONFIRM_STATUS_L4.getColumn()).map(String::valueOf).collect(Collectors.toList());
        } else {
            throw new RomeException(ResponseMsg.FAIL_2014.getCode(), ResponseMsg.FAIL_2014.getMsg());
        }
        return targetList;
    }

    private List<String> getGroupColumns(SalesPlanDirectlyDTO directly) {
        if (CollectionUtils.isNotEmpty(directly.getAreaCodeList())) {
            Integer level = directly.getAreaCodeList().stream().map(SalesPlanSelectDTO::getLevel)
                    .min(Integer::compareTo).orElse(CommonConstants.ZERO);
            return Arrays.asList(getAreaGroupKey(level), EsConmulEnum.CHANNEL_KEYWORD.getFName(),
                    EsConmulEnum.SKU_KEYWORD.getFName());
        } else {
            Integer level = directly.getPermissionAreaList().stream().map(SalesPlanSelectDTO::getLevel)
                    .min(Integer::compareTo).orElse(CommonConstants.ZERO);
            return Arrays.asList(getAreaGroupKey(level), EsConmulEnum.CHANNEL_KEYWORD.getFName(),
                    EsConmulEnum.SKU_KEYWORD.getFName());
        }
    }

    private String getAreaGroupKey(Integer level) {
        String groupArea = "";
        switch (level) {
            case 1:
                groupArea = EsConmulEnum.PROVINCE_CODE_KEYWORD.getFName();
                break;
            case 2:
                groupArea = EsConmulEnum.CITY_CODE_KEYWORD.getFName();
                break;
            case 3:
                groupArea = EsConmulEnum.COUNTY_CODE_KEYWORD.getFName();
                break;
            case 4:
                groupArea = EsConmulEnum.STORE_KEYWORD.getFName();
                break;
            default:
                throw new RomeException(ResponseMsg.PARAM_ERROR.getCode(), ResponseMsg.PARAM_ERROR.getMsg());
        }
        return groupArea;
    }

    /**
     * 获取ES查询参数
     *
     * @param directly
     * @param level
     * @param dateList
     * @param ifGroup
     * @return
     */
    private EsAggregationDTO getEsQuery(SalesPlanDirectlyDTO directly, Integer level, List<String> dateList, Boolean ifGroup) {
        EsAggregationDTO esAggregation = new EsAggregationDTO();
        esAggregation.setUnitType(directly.getUnitType());
        EsQueryDTO esQuery = getQuery(directly);
        List<String> targetKeyList = getTargetKeyList(level);
        esAggregation.setDateList(dateList);
        esAggregation.setEsQuery(esQuery);
        esAggregation.setPageNum(directly.getPageNum());
        esAggregation.setPageSize(directly.getPageSize());
        esAggregation.setSumColumns(targetKeyList);
        esAggregation.setTableCode(TableCodeEnum.DIRECT_FORECAST.getCode());
        esAggregation.setUserId(UserContext.getUserId());
        if (ifGroup) {
            List<String> groupColumns = getGroupColumns(directly);
            esAggregation.setGroupColumns(groupColumns);
        }
        return esAggregation;
    }

    /**
     * 获取ES查询参数
     *
     * @param directly
     * @return
     */
    private EsQueryDTO getQuery(SalesPlanDirectlyDTO directly) {
        EsQueryDTO esQuery = new EsQueryDTO();
        List<SalesPlanSelectDTO> permissionAreaList = permissionService.getPermissionAreaList();
        // 开发测试用
        // List<SalesPlanSelectDTO> permissionAreaList = new ArrayList<>();
        // SalesPlanSelectDTO salesPlanSelectDTO = new SalesPlanSelectDTO();
        // salesPlanSelectDTO.setLevel(1);
        // salesPlanSelectDTO.setCode("310000");
        // permissionAreaList.add(salesPlanSelectDTO);

        if (CollectionUtils.isEmpty(permissionAreaList)) {
            throw new RomeException(ResponseMsg.FAIL_2014.getCode(), ResponseMsg.FAIL_2014.getMsg());
        }
        directly.setPermissionAreaList(permissionAreaList);
        Date startDate = DateUtil.beginOfWeek(directly.getStartTime());
        Date entDate = DateUtil.offsetWeek(startDate, CommonConstants.WEEK_TARGET_SIZE);
        esQuery.setChannelCodeList(directly.getChannelCodeList());
        esQuery.setQueryAreaCodeList(directly.getAreaCodeList());
        esQuery.setPermissionAreaList(permissionAreaList);
        esQuery.setCategoryCodeList(directly.getCategoryCodeList());
        esQuery.setTypeList(directly.getTypeList());
        esQuery.setLayeredCodeList(directly.getLayeredCodeList());
        esQuery.setStartDate(DateUtil.formatDate(startDate));
        esQuery.setEndDate(DateUtil.formatDate(entDate));
        return esQuery;
    }

    private List<DirectlyStoreDTO> getStoreInfo(EsQueryDTO esQuery, List<EsReturnDTO> resultList, Long unitType) {
        List<String> skuCodeList = new ArrayList<>();
        List<String> provinceList = new ArrayList<>();
        List<String> cityList = new ArrayList<>();
        List<String> countyList = new ArrayList<>();
        List<String> storeList = new ArrayList<>();
        for (EsReturnDTO esReturn : resultList) {
            if (StringUtils.isNotEmpty(esReturn.getSkuCode())) {
                skuCodeList.add(esReturn.getSkuCode());
            }
            if (StringUtils.isNotEmpty(esReturn.getAreaCode())) {
                String[] areaArr = esReturn.getAreaCode().split("/");
                switch (areaArr.length) {
                    case 1:
                        provinceList.add(areaArr[0]);
                        break;
                    case 2:
                        cityList.add(areaArr[1]);
                        break;
                    case 3:
                        countyList.add(areaArr[2]);
                        break;
                    case 4:
                        storeList.add(areaArr[3]);
                        break;
                    default:
                        break;
                }
            } else {
                List<SalesPlanSelectDTO> permissionAreaList = esQuery.getPermissionAreaList();
                if (CollectionUtils.isNotEmpty(esQuery.getQueryAreaCodeList())) {
                    permissionAreaList.addAll(esQuery.getQueryAreaCodeList());
                }
                for (SalesPlanSelectDTO area : permissionAreaList) {
                    switch (area.getLevel()) {
                        case 1:
                            provinceList.add(area.getCode());
                            break;
                        case 2:
                            cityList.add(area.getCode());
                            break;
                        case 3:
                            countyList.add(area.getCode());
                            break;
                        case 4:
                            storeList.add(area.getCode());
                            break;
                        default:
                            break;
                    }
                }
            }
        }
        DirectlyStoreDTO directlyStore = new DirectlyStoreDTO();
        directlyStore.setProvinceCodeList(provinceList);
        directlyStore.setCityCodeList(cityList);
        directlyStore.setCountyCodeList(countyList);
        directlyStore.setStoreCodeList(storeList);
        directlyStore.setSkuCodeList(skuCodeList);
        directlyStore.setUnitType(unitType);
        directlyStore.setStartTime(DateUtil.parseDate(esQuery.getStartDate()));
        directlyStore.setEndTime(DateUtil.parseDate(esQuery.getEndDate()));
        return directlyStoreFacade.listByCondition(directlyStore);
    }

    /**
     * 设置指标集合
     *
     * @param result
     * @param targetMap
     * @param permissionLevel
     */
    private void setTargetList(SalesPlanDirectlyReturnDTO result, Map<String, List<BigDecimal>> targetMap, Integer permissionLevel) {
        switch (permissionLevel) {
            case 2:
                for (String key : targetMap.keySet()) {
                    if (key.equals(EsSumColumnEnum.CONFIRM_L2.getColumn())) {
                        result.setConfirmQty(targetMap.get(key));
                        continue;
                    }
                    if (key.equals(SalesPlanDirectlyEnum.CONFIRM_L1.getColumns())) {
                        result.setSubConfirmQty(targetMap.get(key));
                        continue;
                    }
                    setCurrentTarget(result, key, targetMap);
                }
                break;
            case 3:
                for (String key : targetMap.keySet()) {
                    if (key.equals(EsSumColumnEnum.CONFIRM_L3.getColumn())) {
                        result.setConfirmQty(targetMap.get(key));
                        continue;
                    }
                    if (key.equals(EsSumColumnEnum.CONFIRM_L2.getColumn())) {
                        result.setSubConfirmQty(targetMap.get(key));
                        continue;
                    }
                    setCurrentTarget(result, key, targetMap);
                }
                break;
            case 4:
                for (String key : targetMap.keySet()) {
                    if (key.equals(EsSumColumnEnum.CONFIRM_L4.getColumn())) {
                        result.setConfirmQty(targetMap.get(key));
                        continue;
                    }
                    if (key.equals(EsSumColumnEnum.CONFIRM_L3.getColumn())) {
                        result.setSubConfirmQty(targetMap.get(key));
                        continue;
                    }
                    setCurrentTarget(result, key, targetMap);
                }
                break;
            default:
                break;
        }
    }

    private void setCurrentTarget(SalesPlanDirectlyReturnDTO result, String key, Map<String, List<BigDecimal>> targetMap) {
        switch (key) {
            case "predict_sales":
                result.setForecastQty(targetMap.get(key));
                break;
            case "last_predict_sales":
                result.setLastForecastQty(targetMap.get(key));
                break;
            case "predict_sales_difference":
                result.setForecastFlucteQty(targetMap.get(key));
                break;
            case "predict_sales_scale":
                result.setForecastFlucteRateQty(targetMap.get(key));
                break;
            case "last_confirm_l2":
            case "last_confirm_l3":
            case "last_confirm_l4":
                result.setLastConfirmQty(targetMap.get(key));
                break;
            case "confirm_status_l2":
            case "confirm_status_l3":
            case "confirm_status_l4":
                result.setConfirmType(targetMap.get(key));
                break;
            case "predict_confirm_l2_difference":
            case "predict_confirm_l3_difference":
            case "predict_confirm_l4_difference":
                result.setForecastDifferConfirmQty(targetMap.get(key));
                break;
            case "predict_confirm_l2_scale":
            case "predict_confirm_l3_scale":
            case "predict_confirm_l4_scale":
                result.setForecastRateConfirmQty(targetMap.get(key));
                break;
            case "confirm_target_l2":
                result.setConfirmTarget2(targetMap.get(key));
                break;
            case "confirm_target_l3":
                result.setConfirmTarget3(targetMap.get(key));
                break;
            case "confirm_target_l4":
                result.setConfirmTarget4(targetMap.get(key));
                break;
            case "actual_sales":
                result.setActualSalesQty(targetMap.get(key));
                break;
            default:
                break;
        }
    }

    private List<SalesPlanDirectlyReturnDTO> analyzeData(List<EsReturnDTO> paramList, Integer permissionLevel) {
        List<SalesPlanDirectlyReturnDTO> resultList = new ArrayList<>();
        paramList.forEach(item -> {
            SalesPlanDirectlyReturnDTO result = new SalesPlanDirectlyReturnDTO();
            result.setChannel(item.getChannel());
            result.setAreaCode(item.getAreaCode());
            result.setArea(item.getArea());
            result.setCategory(item.getCategory());
            result.setSkuCode(item.getSkuCode());
            result.setSkuName(item.getSkuName());
            result.setStoreStatus(item.getPlanType() != null ? Integer.valueOf(item.getPlanType()) : null);
            setTargetList(result, item.getTargetMap(), permissionLevel);
            resultList.add(result);
        });
        return resultList;
    }

    private List<SalesPlanDirectlyReturnDTO> analyzeExportData(List<EsReturnDTO> paramList, Integer permissionLevel) {
        if (CollectionUtils.isEmpty(paramList)) {
            return null;
        }
        List<SalesPlanDirectlyReturnDTO> resultList = new ArrayList<>();
        for (EsReturnDTO item : paramList) {
            SalesPlanDirectlyReturnDTO result = new SalesPlanDirectlyReturnDTO();
            result.setChannel(item.getChannel());
            result.setChannelName(item.getChannelName());
            result.setAreaCode(item.getAreaCode());
            result.setArea(item.getArea());
            result.setCategory(item.getCategory());
            result.setSkuCode(item.getSkuCode());
            result.setSkuName(item.getSkuName());
            result.setStoreStatus(item.getPlanType() != null ? Integer.valueOf(item.getPlanType()) : null);
            setTargetList(result, item.getTargetMap(), permissionLevel);
            resultList.add(result);
        }
        return resultList;
    }

    // public List<WarehouseReceiveQtyDTO> getStockInAndOut(EsQueryDTO esQuery, List<EsReturnDTO> resultList) {
    //     List<WarehouseReceiveQtyDTO> stockInList = new ArrayList<>();
    //     List<SalesPlanSelectDTO> areaCodeList = esQuery.getQueryAreaCodeList();
    //     List<String> areaList = resultList.stream().filter(v -> v.getAreaCode() != null)
    //             .map(EsReturnDTO::getAreaCode).collect(Collectors.toList());
    //     // 判断结果集是否有区域信息
    //     if (CollectionUtils.isNotEmpty(areaList)) {
    //         // 判断是否有有门店的查询条件
    //         if (CollectionUtils.isNotEmpty(areaCodeList) &&
    //                 areaCodeList.stream().allMatch(e -> e.getLevel().equals(CommonConstants.AREA_LEVEL_FOUR))) {
    //             // 获取门店集合
    //             List<String> storeCodeList = areaCodeList.stream()
    //                     .filter(e -> e.getLevel().equals(CommonConstants.AREA_LEVEL_FOUR))
    //                     .map(SalesPlanSelectDTO::getCode).collect(Collectors.toList());
    //             List<String> areaCodes = new ArrayList<>();
    //             areaList.forEach(area -> areaCodes.addAll(Arrays.asList(area.split("/"))));
    //             storeCodeList = storeCodeList.stream().filter(s -> areaCodes.stream().anyMatch(s::equals))
    //                     .distinct().collect(Collectors.toList());
    //             if (CollectionUtils.isNotEmpty(storeCodeList)) {
    //                 stockInList = getStockData(resultList, storeCodeList, esQuery);
    //             }
    //         } else {
    //             // 获取渠道code
    //             List<SearchSourceToCQueryDTO> tocQueryData = getTocQueryData(areaList);
    //             List<String> factoryList = tocQueryData.stream().filter(e -> StringUtils.isNotEmpty(e.getWarehouseCode()))
    //                     .map(SearchSourceToCQueryDTO::getWarehouseCode).distinct().collect(Collectors.toList());
    //             stockInList = getStockData(resultList, factoryList, esQuery);
    //         }
    //     } else {
    //         // 获取所有查询区域和权限区域所mapping的仓
    //         List<SalesPlanSelectDTO> permissionAreaList = esQuery.getPermissionAreaList();
    //         if (CollectionUtils.isNotEmpty(areaCodeList)) {
    //             permissionAreaList.addAll(areaCodeList);
    //         }
    //         if (permissionAreaList.stream().allMatch(e -> e.getLevel().equals(CommonConstants.AREA_LEVEL_FOUR))) {
    //             List<String> storeCodeList = permissionAreaList.stream()
    //                     .filter(e -> e.getLevel().equals(CommonConstants.AREA_LEVEL_FOUR))
    //                     .map(SalesPlanSelectDTO::getCode).collect(Collectors.toList());
    //             stockInList = getStockData(resultList, storeCodeList, esQuery);
    //         } else {
    //             List<String> areas = permissionAreaList.stream().map(SalesPlanSelectDTO::getCode).distinct().collect(Collectors.toList());
    //             List<SearchSourceToCQueryDTO> tocQueryData = getTocQueryData(areas);
    //             List<String> factoryList = tocQueryData.stream().filter(e -> StringUtils.isNotEmpty(e.getWarehouseCode()))
    //                     .map(SearchSourceToCQueryDTO::getWarehouseCode).distinct().collect(Collectors.toList());
    //             stockInList = getStockData(resultList, factoryList, esQuery);
    //         }
    //     }
    //     return stockInList;
    // }
    //
    // private List<WarehouseReceiveQtyDTO> getStockData(List<EsReturnDTO> resultList, List<String> codeList, EsQueryDTO esQuery) {
    //     List<String> skuCodeList = resultList.stream().map(EsReturnDTO::getSkuCode).distinct().collect(Collectors.toList());
    //     List<WarehouseReceiveQtyDTO> stockInList = new ArrayList<>();
    //     if (CollectionUtils.isNotEmpty(skuCodeList)) {
    //         codeList.forEach(val -> {
    //             StockInAndOutDTO stockInAndOut = new StockInAndOutDTO();
    //             stockInAndOut.setSkuCodeList(skuCodeList);
    //             stockInAndOut.setFactoryCode(val);
    //             stockInAndOut.setStartTime(esQuery.getStartDate());
    //             stockInAndOut.setEndTime(DateUtil.formatDate(DateUtil.endOfWeek(new Date())));
    //             stockInList.addAll(blOlapFacade.getStockInAndOut(stockInAndOut));
    //         });
    //     } else {
    //         List<StockInAndOutDTO> paramList = getFactoryStock(esQuery, codeList);
    //         paramList.forEach(param -> stockInList.addAll(blOlapFacade.getStockIn(param)));
    //     }
    //     return stockInList;
    // }
    //
    // private List<StockInAndOutDTO> getFactoryStock(EsQueryDTO esQuery, List<String> codeList) {
    //     List<StockInAndOutDTO> paramList = new ArrayList<>();
    //     List<SalesPlanSelectDTO> categoryList = esQuery.getCategoryCodeList();
    //     String startDate = esQuery.getStartDate();
    //     String endDate = DateUtil.formatDate(DateUtil.endOfWeek(new Date()));
    //     for (SalesPlanSelectDTO planSelect : categoryList) {
    //         StockInAndOutDTO stockInAndOut = new StockInAndOutDTO();
    //         switch (planSelect.getLevel()) {
    //             case 2:
    //                 stockInAndOut.setCategoryTwoCode(planSelect.getCode());
    //                 stockInAndOut.setCodeList(codeList);
    //                 stockInAndOut.setCodeType(WareHouseTypeEnum.TYPE_WAREHOUSE.getType());
    //                 stockInAndOut.setStartTime(startDate);
    //                 stockInAndOut.setEndTime(endDate);
    //                 paramList.add(stockInAndOut);
    //                 break;
    //             case 3:
    //                 stockInAndOut.setCategoryThreeCode(planSelect.getCode());
    //                 stockInAndOut.setCodeList(codeList);
    //                 stockInAndOut.setCodeType(WareHouseTypeEnum.TYPE_WAREHOUSE.getType());
    //                 stockInAndOut.setStartTime(startDate);
    //                 stockInAndOut.setEndTime(endDate);
    //                 paramList.add(stockInAndOut);
    //                 break;
    //             case 4:
    //                 stockInAndOut.setCategoryFourCode(planSelect.getCode());
    //                 stockInAndOut.setCodeList(codeList);
    //                 stockInAndOut.setCodeType(WareHouseTypeEnum.TYPE_WAREHOUSE.getType());
    //                 stockInAndOut.setStartTime(startDate);
    //                 stockInAndOut.setEndTime(endDate);
    //                 paramList.add(stockInAndOut);
    //                 break;
    //             default:
    //                 stockInAndOut.setCodeList(codeList);
    //                 stockInAndOut.setCodeType(WareHouseTypeEnum.TYPE_WAREHOUSE.getType());
    //                 stockInAndOut.setStartTime(startDate);
    //                 stockInAndOut.setEndTime(endDate);
    //                 paramList.add(stockInAndOut);
    //                 break;
    //         }
    //     }
    //     return paramList;
    // }

    // private List<SearchSourceToCQueryDTO> getTocQueryData(List<String> areaList) {
    //     List<SearchSourceToCQueryDTO> queryTocList = new ArrayList<>();
    //     areaList.forEach(area -> {
    //         SearchSourceToCQueryDTO queryToC = new SearchSourceToCQueryDTO();
    //         queryToC.setChannelCode(ChannelTypeEnum.DIRECTLY_OPERATE.getCode());
    //         getQueryToc(area, queryToC);
    //         queryTocList.add(queryToC);
    //     });
    //     return nateWorkFacade.searchToCSource(queryTocList);
    // }

    // private void getQueryToc(String area, SearchSourceToCQueryDTO queryToC) {
    //     String[] areaArr = area.split("/");
    //     switch (areaArr.length) {
    //         case 1:
    //             queryToC.setProvinceCode(areaArr[0]);
    //             break;
    //         case 2:
    //             queryToC.setProvinceCode(areaArr[0]);
    //             queryToC.setCityCode(areaArr[1]);
    //             break;
    //         case 3:
    //             queryToC.setProvinceCode(areaArr[0]);
    //             queryToC.setCityCode(areaArr[1]);
    //             queryToC.setCounty(areaArr[2]);
    //             break;
    //         default:
    //             break;
    //     }
    // }

    // private void setStock(List<EsReturnDTO> paramList, List<WarehouseReceiveQtyDTO> stockInAndOut, List<Map<String, String>> dateMap, List<DirectlyStoreDTO> storeInfoList, Boolean aTrue) {
    //     String sKey = "startTime";
    //     String eKey = "endTime";
    //     for (EsReturnDTO e : paramList) {
    // List<BigDecimal> actualList = new ArrayList<>();
    // if (CollectionUtils.isEmpty(stockInAndOut)) {
    //     dateMap.forEach(date -> actualList.add(BigDecimal.ZERO));
    //     targetMap.put(SalesPlanDirectlyEnum.ACTUAL_RECEIPT.getColumns(), actualList);
    // } else {
    //     if (aTrue) {
    //         dateMap.forEach(map -> actualList.add(stockInAndOut.stream()
    //                 .filter(s -> s.getProductCode().equals(e.getSkuCode()) &&
    //                         DateUtil.parse(s.getDateTime()).compareTo(DateUtil.parseDate(map.get(sKey))) >= 0 &&
    //                         DateUtil.parse(s.getDateTime()).compareTo(DateUtil.parseDate(map.get(eKey))) <= 0)
    //                 .map(v -> ObjectUtils.isNotEmpty(v) ? v.getArrivalXgCount() : BigDecimal.ZERO)
    //                 .reduce(BigDecimal.ZERO, BigDecimal::add)));
    //
    //     } else {
    //         dateMap.forEach(map -> actualList.add(stockInAndOut.stream()
    //                 .filter(s -> DateUtil.parse(s.getDateTime()).compareTo(DateUtil.parseDate(map.get(sKey))) >= 0 &&
    //                         DateUtil.parse(s.getDateTime()).compareTo(DateUtil.parseDate(map.get(eKey))) <= 0)
    //                 .map(v -> ObjectUtils.isNotEmpty(v) ? v.getArrivalXgCount() : BigDecimal.ZERO)
    //                 .reduce(BigDecimal.ZERO, BigDecimal::add)));
    //
    //     }
    //     targetMap.put(SalesPlanDirectlyEnum.ACTUAL_RECEIPT.getColumns(), actualList);
    // }
    // }
    // }

    /**
     * 构造全的列返回数据
     *
     * @return
     */
    private List<SalesPlanDirectlyReturnDTO> getAllReturn() {
        int size = 14;
        List<BigDecimal> qtyList = new ArrayList<>(size);
        for (int i = 0; i < size; i++) {
            qtyList.add(BigDecimal.ZERO);
        }
        SalesPlanDirectlyReturnDTO returnE = new SalesPlanDirectlyReturnDTO();
        returnE.setForecastQty(qtyList);
        returnE.setLastForecastQty(qtyList);
        returnE.setForecastRateConfirmQty(qtyList);
        returnE.setForecastFlucteRateQty(qtyList);
        returnE.setConfirmQty(qtyList);
        returnE.setLastConfirmQty(qtyList);
        returnE.setSubConfirmQty(qtyList);
        returnE.setForecastRateConfirmQty(qtyList);
        returnE.setForecastDifferConfirmQty(qtyList);
        // returnE.setActualReceiptQty(qtyList);
        // returnE.setRealTimeInventoryQty(qtyList);
        return Collections.singletonList(returnE);
    }

    private void getOtherTarget(EsQueryDTO esQuery, List<EsReturnDTO> paramList, List<Map<String, String>> weekDates, Integer level, Boolean aFalse, Long unitType) {
        if (level.equals(CommonConstants.AREA_LEVEL_TWO)) {
            // 获取门店确认量
            List<DirectlyStoreDTO> storeInfoList = getStoreInfo(esQuery, paramList, unitType);
            setStoreInfo(paramList, esQuery.getQueryAreaCodeList(), weekDates, storeInfoList, aFalse);
        }
        // todo 暂时不需要 到货量
        // List<WarehouseReceiveQtyDTO> stockInAndOut = getStockInAndOut(esQuery, paramList);
        // setStock(paramList, null, weekDates, storeInfoList, aFalse);
    }

    private void setStoreInfo(List<EsReturnDTO> paramList, List<SalesPlanSelectDTO> areaCodeList, List<Map<String, String>> dateMap, List<DirectlyStoreDTO> storeInfoList, Boolean aTrue) {
        String sKey = "startTime";
        String eKey = "endTime";
        for (EsReturnDTO e : paramList) {
            Map<String, List<BigDecimal>> targetMap = e.getTargetMap();
            List<BigDecimal> confirmList = new ArrayList<>();
            if (CollectionUtils.isEmpty(storeInfoList)) {
                dateMap.forEach(date -> confirmList.add(BigDecimal.ZERO));
                targetMap.put(SalesPlanDirectlyEnum.CONFIRM_L1.getColumns(), confirmList);
            } else {
                if (aTrue) {
                    if (CollectionUtils.isNotEmpty(areaCodeList) &&
                            areaCodeList.stream().anyMatch(v -> v.getLevel().equals(CommonConstants.AREA_LEVEL_FOUR))) {
                        for (EsReturnDTO es : paramList) {
                            if (CollectionUtils.isNotEmpty(storeInfoList)) {
                                String store = es.getAreaCode().split("/")[3];
                                storeInfoList.stream().filter(s -> s.getStoreCode().equals(store))
                                        .forEach(v -> es.setPlanType(v.getStatus().toString()));
                            } else {
                                es.setPlanType("0");
                            }
                        }
                    }
                    dateMap.forEach(map -> confirmList.add(storeInfoList.stream()
                            .filter(s -> (e.getAreaCode().contains(s.getProvinceCode()) ||
                                    e.getAreaCode().contains(s.getCityCode()) || e.getAreaCode().contains(s.getCountyCode()) ||
                                    e.getAreaCode().contains(s.getStoreCode())) && s.getSkuCode().equals(e.getSkuCode()) &&
                                    s.getFormulateDate().compareTo(DateUtil.parseDate(map.get(sKey))) >= 0 &&
                                    s.getFormulateDate().compareTo(DateUtil.parseDate(map.get(eKey))) <= 0)
                            .map(v -> ObjectUtils.isNotEmpty(v) ? v.getConfirmQty() : BigDecimal.ZERO)
                            .reduce(BigDecimal.ZERO, BigDecimal::add)));
                } else {
                    dateMap.forEach(map -> confirmList.add(storeInfoList.stream()
                            .filter(s -> s.getFormulateDate().compareTo(DateUtil.parseDate(map.get(sKey))) >= 0 &&
                                    s.getFormulateDate().compareTo(DateUtil.parseDate(map.get(eKey))) <= 0)
                            .map(v -> ObjectUtils.isNotEmpty(v) ? v.getConfirmQty() : BigDecimal.ZERO)
                            .reduce(BigDecimal.ZERO, BigDecimal::add)));
                }

                targetMap.put(SalesPlanDirectlyEnum.CONFIRM_L1.getColumns(), confirmList);
            }
        }

    }

    private EsExportAggregationDTO TransferToExportAggregation(EsAggregationDTO esQuery) {
        EsExportAggregationDTO esExportAggregationDTO = new EsExportAggregationDTO();
        esExportAggregationDTO.setAfterKey("");
        esExportAggregationDTO.setDateList(esQuery.getDateList());
        esExportAggregationDTO.setEsQuery(esQuery.getEsQuery());
        esExportAggregationDTO.setGroupColumns(esQuery.getGroupColumns());
        esExportAggregationDTO.setSumColumns(esQuery.getSumColumns());
        return esExportAggregationDTO;
    }

    private void getExportDataList(List<List<Object>> exportDataList, List<SalesPlanDirectlyReturnDTO> resultList, List<String> allTargetsDesc) {
        if (CollectionUtils.isEmpty(resultList)) {
            return;
        }
        List<Object> itemRow;
        List<BigDecimal> list1;
        List<BigDecimal> list2;
        List<BigDecimal> list3;
        List<BigDecimal> list4;
        List<BigDecimal> list5;
        List<BigDecimal> list6;
        List<BigDecimal> list7;
        List<BigDecimal> list8;
        List<BigDecimal> list9;
        List<BigDecimal> list10;
        List<BigDecimal> list11;
        List<BigDecimal> list12;
        List<BigDecimal> list13;
        for (SalesPlanDirectlyReturnDTO item : resultList) {
            list1 = item.getForecastQty();
            list2 = item.getLastForecastQty();
            list3 = item.getForecastFlucteQty();
            list4 = item.getForecastFlucteRateQty();
            list5 = item.getConfirmQty();
            list6 = item.getLastConfirmQty();
            list7 = item.getSubConfirmQty();
            list8 = item.getConfirmTarget2();
            list9 = item.getConfirmTarget3();
            list10 = item.getConfirmTarget4();
            list11 = item.getForecastDifferConfirmQty();
            list12 = item.getForecastRateConfirmQty();
            list13 = item.getActualSalesQty();
            int actualIndex = 0;
            for (String target : allTargetsDesc) {
                itemRow = new ArrayList<>();
                itemRow.add(item.getChannelName());
                itemRow.add(item.getArea());
                itemRow.add(item.getCategory());
                itemRow.add(item.getSkuName() + "/" + item.getSkuCode());
                itemRow.add(target);
                //加入数据
                for (int j = 0; j < DataDisplayCycleEnum.WEEKLY_FOURTEEN.getValue(); j++) {
                    //获取指标集合，这里没有排序，默认使用枚举的顺序
                    switch (actualIndex) {
                        case 0:
                            itemRow.add(list1.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list1.get(j));
                            break;
                        case 1:
                            itemRow.add(list2.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list2.get(j));
                            break;
                        case 2:
                            itemRow.add(list3.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list3.get(j));
                            break;
                        case 3:
                            itemRow.add(list4.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list4.get(j));
                            break;
                        case 4:
                            itemRow.add(list5.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list5.get(j));
                            break;
                        case 5:
                            itemRow.add(list6.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list6.get(j));
                            break;
                        case 6:
                            itemRow.add(list7.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list7.get(j));
                            break;
                        case 7:
                            itemRow.add(list8.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list8.get(j));
                            break;
                        case 8:
                            itemRow.add(list9.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list9.get(j));
                            break;
                        case 9:
                            itemRow.add(list10.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list10.get(j));
                            break;
                        case 10:
                            itemRow.add(list11.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list11.get(j));
                            break;
                        case 11:
                            itemRow.add(list12.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list12.get(j));
                            break;
                        case 12:
                            itemRow.add(list13.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list13.get(j));
                            break;
                        default:
                            break;
                    }
                }
                actualIndex++;
                exportDataList.add(itemRow);
            }
        }
    }

    private SalesPlanDirectlyDTO transferToDirectlyDTO(ExcelExportDTO excelExportDTO) {
        SalesPlanDirectlyDTO salesPlanDirectlyDTO = new SalesPlanDirectlyDTO();
        salesPlanDirectlyDTO.setTypeList(excelExportDTO.getTypeList());
        salesPlanDirectlyDTO.setAreaCodeList(excelExportDTO.getAreaCodeList());
        salesPlanDirectlyDTO.setCategoryCodeList(excelExportDTO.getCategoryCodeList());
        salesPlanDirectlyDTO.setLayeredCodeList(excelExportDTO.getLayeredCodeList());
        salesPlanDirectlyDTO.setStartTime(excelExportDTO.getStartTime());
        salesPlanDirectlyDTO.setUnitType(excelExportDTO.getUnitType());
        salesPlanDirectlyDTO.setPageNum(excelExportDTO.getPageNum());
        salesPlanDirectlyDTO.setPageSize(excelExportDTO.getPageSize());
        return salesPlanDirectlyDTO;
    }


    private void setTargetTitle(List<List<String>> mainHeaders) {
        List<String> targetTitle = new ArrayList<>();
        targetTitle.add(ExcelExportTitleEnum.TARGET_TITLE.getTitle());
        mainHeaders.add(targetTitle);
    }

    private List<List<String>> getMainHeaders() {
        List<List<String>> mainHeaders = new ArrayList<>();
        AdvancedSearchUtil.setList(mainHeaders, ExcelExportTitleEnum.CHANNEL_TITLE.getTitle());
        AdvancedSearchUtil.setList(mainHeaders, ExcelExportTitleEnum.AREA_TITLE.getTitle());
        AdvancedSearchUtil.setList(mainHeaders, ExcelExportTitleEnum.CATEGORY_TITLE.getTitle());
        AdvancedSearchUtil.setList(mainHeaders, ExcelExportTitleEnum.SKU_MAIN_TITLE.getTitle());
        return mainHeaders;
    }
}
